﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Reflection;

namespace Handrise.CDCable.Business
{
    public class CommonFunction
    {
        public static string GetLocalPath()
        {
            string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);

            if (path.StartsWith("file:\\"))
                return path.Remove(0, 6);
            else
                return path;
        }

        /// <summary>
        /// 获取xml中的单节
        /// </summary>
        /// <param name="xmlDoc"></param>
        /// <param name="nodePath"></param>
        /// <returns></returns>
        public static XmlNode GetXmlNode(XmlDocument xmlDoc, string nodePath)
        {
            if (xmlDoc == null)
                return null;

            XmlNode nodtReturn = null;
            try
            {
                //根据指定路径获取节点
                nodtReturn = xmlDoc.SelectSingleNode(nodePath);

            }
            catch
            {

            }
            return nodtReturn;
        }

        /// <summary>
        /// 从XML中获取实体
        /// </summary>
        /// <param name="entityXmlNode">对应的XML节点</param>
        /// <param name="entityType">对应的实体类型</param>
        /// <returns></returns>
        public static object GetEntityFromXML(XmlNode entityXmlNode,Type entityType)
        {
            try
            {
                object entity = Activator.CreateInstance(entityType);

                foreach (PropertyInfo proInfo in entityType.GetProperties())
                {
                    string colName;
                    object[] attributeArr = proInfo.GetCustomAttributes(typeof(EntityMappingAttribute), false);
                    if (attributeArr != null && attributeArr.Length == 1)
                    {
                        EntityMappingAttribute attributeMap = (EntityMappingAttribute)attributeArr[0];
                        colName = attributeMap.ColumnName;
                    }
                    else
                    {
                        colName = proInfo.Name.ToLower();
                    }

                    //获取对应属性的值
                    XmlNode xnValue = entityXmlNode.SelectSingleNode(colName);

                    //设置实现属性
                    try
                    {
                        if (xnValue != null)
                        {
                            string typeFullName = proInfo.PropertyType.FullName;

                            if(typeFullName.Contains("System.String"))
                                proInfo.SetValue(entity, xnValue.InnerXml, null);
                            else if (typeFullName.Contains("System.Int32"))
                                proInfo.SetValue(entity, int.Parse(xnValue.InnerXml), null);
                            else if (typeFullName.Contains("System.DateTime"))
                                proInfo.SetValue(entity, DateTime.Parse(xnValue.InnerXml), null);
                            else if (typeFullName.Contains("Boolean"))
                                proInfo.SetValue(entity, bool.Parse(xnValue.InnerXml), null);
                            else
                                proInfo.SetValue(entity, xnValue.InnerXml, null);


                        }
                    }
                    catch (Exception e)
                    {
                        //设置单个实体属性错误
                    }
                }

                return entity;

            }
            catch (Exception e)
            {
                //实体转换失败
                return null;
            }

        }

        /// <summary>
        /// 从XML中获取多个实体
        /// </summary>
        /// <param name="xnData">对应的XML节点</param>
        /// <param name="entityType">对应的实体类型</param>
        /// <returns></returns>
        public static List<Object> GetEntitysFromXML(XmlNode xnData, Type entityType)
        {
            List<Object> returnEntitys = new List<object>();
            try
            {
                string listName = "";
                string entityName = "";
                int dataType = 0;
                //获取实体列表名和实体名称
                object[] attributeArr = entityType.GetCustomAttributes(typeof(EntityMappingAttribute), false);
                EntityMappingAttribute attributeMap;
                if (attributeArr != null && attributeArr.Length == 1)
                {
                    attributeMap = (EntityMappingAttribute)attributeArr[0];
                    listName = attributeMap.ListName;
                    entityName = attributeMap.EntityName;
                    dataType = attributeMap.DataType;
                }
                else
                {
                    listName = entityType.Name.ToLower() + "s";
                    entityName = entityType.Name.ToLower();
                    dataType = 0;
                }

                //从xml中获取获取对应实体列
                XmlNode xnEntitys = xnData.SelectSingleNode(listName);
                if (xnEntitys == null || xnEntitys.ChildNodes.Count == 0)
                    return returnEntitys;


                foreach (XmlNode xnEntity in xnEntitys.ChildNodes)
                {
                    Object entity = GetEntityFromXML(xnEntity, entityType);
                    if (entity != null)
                        returnEntitys.Add(entity);
                }

                return returnEntitys;
            }
            catch (Exception e)
            {
                return returnEntitys;
            }

        
        }

        /// <summary>
        /// 把实体列表设置成XML字符串
        /// </summary>
        /// <param name="entitys">实体列表</param>
        /// <param name="entityType">实体类型</param>
        /// <returns></returns>
        public static string GetXMLFromEnitys<T>(List<T> entitys, Type entityType)
        {
            try
            {
                string listName = "";
                string entityName = "";
                string returnXML = "";
                bool isDevice = true;
                //获取实体列表名和实体名称
                object[] attributeArr = entityType.GetCustomAttributes(typeof(EntityMappingAttribute), false);
                EntityMappingAttribute attributeMap;
                if (attributeArr != null && attributeArr.Length == 1)
                {
                    attributeMap = (EntityMappingAttribute)attributeArr[0];
                    listName = attributeMap.UploadListName;
                    entityName = attributeMap.UploadEntityName;
                }
                else
                {
                    listName = entityType.Name.ToLower() + "s";
                    entityName = entityType.Name.ToLower();
                    isDevice = true;
                }

                //获取实体的每个属性对应主站实体属性的名称，并生成xml字符串
                returnXML += "<" + listName + ">";
                foreach (object entity in entitys)
                {
                    returnXML += "<" + entityName + ">";
                    foreach (PropertyInfo proInfo in entityType.GetProperties())
                    {
                        string colName = "";
                        attributeArr = proInfo.GetCustomAttributes(typeof(EntityMappingAttribute), false);
                        if (attributeArr != null && attributeArr.Length == 1)
                        {
                            attributeMap = (EntityMappingAttribute)attributeArr[0];
                            colName = attributeMap.UploadColumnName;
                        }

                        //没有设置上传列属性，则不上传该列
                        if (string.IsNullOrEmpty(colName))
                            continue;

                        //设置属性内容
                        try
                        {
                            returnXML += "<" + colName + ">" + proInfo.GetValue(entity, null).ToString() + "</" + colName + ">";

                        }
                        catch 
                        {
                        }

                    }
                    returnXML += "</" + entityName + ">";
                }
                returnXML += "</" + listName + ">";

                return returnXML;
            }
            catch (Exception e)
            {
                
                return "";
            }

        }

        /// <summary>
        /// 将普通文本转换成Base64编码的文本
        /// </summary>
        /// <param name="value">普通文本</param>
        /// <returns></returns>
        public static string StringToBase64String(String value)
        {
            byte[] binBuffer = (new UnicodeEncoding()).GetBytes(value);
            int base64ArraySize = (int)Math.Ceiling(binBuffer.Length / 3d) * 4;
            char[] charBuffer = new char[base64ArraySize];
            Convert.ToBase64CharArray(binBuffer, 0, binBuffer.Length, charBuffer, 0);
            string s = new string(charBuffer);
            return s;
        }

        /// <summary>
        /// 将Base64编码的文本转换成普通文本
        /// </summary>
        /// <param name="base64">Base64编码的文本</param>
        /// <returns></returns>
        public static string Base64StringToString(string base64)
        {
            byte[] bContent = Convert.FromBase64String(base64);
            return System.Text.Encoding.Default.GetString(bContent);
        }

        /// <summary>
        /// 将Byte[]转换成Base64编码文本
        /// </summary>
        /// <param name="binBuffer">Byte[]</param>
        /// <returns></returns>
        public static string toBase64(byte[] binBuffer)
        {
            return Convert.ToBase64String(binBuffer);
            //int base64ArraySize = (int)Math.Ceiling(binBuffer.Length / 3d) * 4;
            //char[] charBuffer = new char[base64ArraySize];
            //Convert.ToBase64CharArray(binBuffer, 0, binBuffer.Length, charBuffer, 0);
            //string s = new string(charBuffer);
            //return s;
        }

        /// <summary>
        /// 将Base64编码文本转换成Byte[]
        /// </summary>
        /// <param name="base64">Base64编码文本</param>
        /// <returns></returns>
        public static Byte[] Base64ToBytes(string base64)
        {
            char[] charBuffer = base64.ToCharArray();
            byte[] bytes = Convert.FromBase64CharArray(charBuffer, 0, charBuffer.Length);
            return bytes;
        }

        /// <summary>
        /// 创建发送数据
        /// </summary>
        /// <param name="requestOperate">请求的操作</param>
        /// <param name="serviceName"></param>
        /// <param name="parameters">参数</param>
        /// <param name="writeLog">是否让主站服务器写日志</param>
        /// <returns></returns>
        public static string BuildSendData(string requestOperate, string serviceName, List<MessageParameter> parameters, bool writeLog)
        {
            string data = "<message><operation namespace=\"http://com.techstar/cablePdaData/" + serviceName + "\"  name=\"" + requestOperate + "\"><parameters>";
            foreach (MessageParameter parameter in parameters)
            {
                data += "<parameter>";
                data += "<name>" + parameter.Name + "</name>";
                data += "<type>" + parameter.Type + "</type>";
                data += "<value><![CDATA[" + parameter.Value + "]]></value>";
                data += "</parameter>";
            }
            data += "</parameters></operation><control><log><parameters><parameter>";
            data += "<name>systemLog</name><type>bool</type><value><![CDATA[" + writeLog.ToString().ToLower() + "]]></value>";
            data += "</parameter></parameters></log></control></message>";

            return data;
        }

        /// <summary>
        /// 返回的数据是否正确
        /// </summary>
        /// <param name="receiveData"></param>
        /// <returns></returns>
        public static bool ReturnDataIsOk(string receiveData)
        {
            try
            {
                //处理数据
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(receiveData);
                //先尝试获取正确的返回结果
                XmlNode xnValue = CommonFunction.GetXmlNode(xmlDoc, "message/operation/returnValue/value");
                if (xnValue == null)
                {
                    //没有正确的返回结果
                    return false;
                }

                return true;
            }
            catch (Exception e)
            {
                return false;
            }

        }
    }
}
